package com.panovue.dataextraction.reader;

import cn.edu.hfut.dmic.webcollector.model.CrawlDatum;
import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.hutool.core.io.FileUtil;
import com.panovue.dataextraction.Main;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;

import java.io.File;

import static com.panovue.dataextraction.ReaderUtil.saveFile;
import static com.panovue.dataextraction.ReaderUtil.saveImage;

/**
 * proteinatlas 解析
 */
@Slf4j
public class ProTeiNatLasReader extends AbstractReader {

    public ProTeiNatLasReader() {
        super("ProTeiNatLas", true);
    }

    public ProTeiNatLasReader(String key) {
        super("ProTeiNatLas", true);
        this.key = key;
        baseUrl = "https://www.proteinatlas.org/";
        baseDir += key + File.separator + "ProTeiNatLas" + File.separator;

        buildDriver(true);

        addSeed("https://www.proteinatlas.org/search/" + key);
        // 设置线程数
        setThreads(16);
        // 开始爬取
        try {
            start(10);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public void visit(Page page, CrawlDatums next) {
        String type = page.meta("type");

        Elements table = page.select("table");
        if (page.url().contains("search")) {
            String href = table.first().selectFirst("#searchResult > tbody.searchResult.no_styled_a > tr > td:nth-child(1) > a").attr("href");
            next.addAndReturn(baseUrl + href).meta("type", "details");
        } else if ("details".equals(type)) {
            data.set("marker背景", page.select("td.top").last().text());
            data.set("marker别名", page.selectText("body > table > tbody > tr > td:nth-child(2) > div > table:nth-child(2) > tbody > tr:nth-child(3) > td"));
            data.set("细胞定位", page.selectText("body > table > tbody > tr > td:nth-child(2) > div > table:nth-child(3) > tbody > tr:nth-child(4) > td"));
            data.set("组织特异性", page.selectText("body > table > tbody > tr > td:nth-child(2) > div > table:nth-child(4) > tbody > tr:nth-child(2) > td:nth-child(2)"));
            data.set("组织表达簇", page.selectText("body > table > tbody > tr > td:nth-child(2) > div > table:nth-child(4) > tbody > tr:nth-child(3) > td"));

            data.set("细胞特异性", page.selectText("body > table > tbody > tr > td:nth-child(2) > div > table:nth-child(5) > tbody > tr:nth-child(2) > td:nth-child(2)"));
            data.set("细胞表达簇", page.select("span:contains(Immune cell)").last().parent().parent().select("td").text());
            FileUtil.writeUtf8String(data.toString(), baseDir + File.separator + key + ".json");
            String href = page.select("p:contains(TISSUE)").first().parent().parent().attr("href");
            next.addAndReturn(baseUrl + href).meta("type", "details_tissue");
        } else if ("details_tissue".equals(type)) {
            driver.get(page.url());
            WebElement PROTEIN_EXPRESSION_OVERVIEW = driver.findElement(By.className("main_table")).findElement(By.tagName("table")).findElement(By.xpath("/html/body/table/tbody/tr/td[2]/div/table[4]"));
            saveImage(PROTEIN_EXPRESSION_OVERVIEW, baseDir + File.separator + "TISSUE" + File.separator + "PROTEIN_EXPRESSION_OVERVIEW");
            Element element = page.select("span:contains(ASSAYS)").get(1).parent().parent().parent().select("img").first();
            String imgSrc = element.attr("src");
            saveFile("https:" + imgSrc, baseDir + File.separator + "TISSUE" + File.separator + imgSrc.substring(imgSrc.lastIndexOf('/') + 1));

            String href = page.select(".uberon:contains(Soft tissue)").attr("href");
            next.addAndReturn(baseUrl + href).meta("type", "details_tissue_image");


        } else if ("details_tissue_image".equals(type)) {
            log.info(page.selectText("title"));
            Elements select = page.select("a[target=_blank].imid");
            for (Element element : select) {
//                executorService.submit(() -> {
                String imgSrc = element.attr("href");
                String id = element.attr("id");
                saveFile("https:" + imgSrc, baseDir + File.separator + "TISSUE" + File.separator + id + ".jpg");
//                });
            }
            String href = page.select("p:contains(PATHOLOGY)").first().parent().parent().attr("href");
            next.addAndReturn(baseUrl + href).meta("type", "PATHOLOGY");
        } else if ("PATHOLOGY".equals(type)) {
            driver.get(page.url());
            JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
            WebElement PROTEIN_EXPRESSION = driver.findElement(By.className("main_table")).findElement(By.xpath("//table[4]"));
            jsExecutor.executeScript("arguments[0].scrollIntoView(true);", PROTEIN_EXPRESSION);
            saveImage(PROTEIN_EXPRESSION, baseDir + File.separator + "PATHOLOGY" + File.separator + "PROTEIN_EXPRESSION");
        }
    }

    @MatchCode(codes = {503})
    public void visitRetry(Page page, CrawlDatums next) {
        try {
            next.addAndReturn(page.url()).meta("type", page.meta("type"));
        } catch (Exception e) {
            ExceptionUtils.fail(e);
        }
    }

    @Override
    public void execute(CrawlDatum datum, CrawlDatums next) throws Exception {
        super.execute(datum, next);
        log.info("PRI URL：{}", datum.url());
    }

    @Override
    public void afterStop() {
        if (driver != null) {
            driver.quit();
        }
        log.info("背景信息调研 完成");
    }

//    @Override
//    public void parser() {
//        driver.get(baseUrl + "search/" + key);
//        log.info("proteinatlas 解析开始");
//
//        String page = driver.findElement(By.id("searchResult")).getAttribute("outerHTML");
//        Document searchResult = Jsoup.parse(page);
//
//        String href = searchResult.getElementsByAttributeValueMatching("href", key).first().attributes().get("href");
//        // 打开网页
//        driver.get(baseUrl + href);
//        WebElement main_table = driver.findElement(By.className("main_table"));
//
////        main_table(main_table);
////
//        List<WebElement> tables = new LinkedList<>();
//
//        for (int i = 1; i <= 4 || i == 7; i++) {
//            String xpath = String.format("/html/body/table/tbody/tr/td[2]/div/table[%d]", i);
//            WebElement table = main_table.findElement(By.xpath(xpath));
//            tables.add(table);
//        }
//
//
//        for (WebElement table : tables) {
//            Document outerHTML = Jsoup.parse(table.getAttribute("outerHTML"));
//            String title = outerHTML.getElementsByTag("th").first().html();
//            saveImage(table, key + File.separator + title);
//        }
//
//
//        driver.findElement(By.cssSelector(".atlas_header a[title='Tissue - Enhanced']")).click();
//
//
//        main_table = driver.findElement(By.className("main_table"));
//
//        WebElement PROTEIN_EXPRESSION_OVERVIEW = main_table.findElement(By.tagName("table")).findElement(By.xpath("/html/body/table/tbody/tr/td[2]/div/table[4]"));
//        saveImage(PROTEIN_EXPRESSION_OVERVIEW, key + File.separator + "PROTEIN_EXPRESSION_OVERVIEW");
//
//
//        driver.findElement(By.cssSelector(".atlas_header a[title='Pathology - Enhanced']")).click();
//
//        JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
//
//        main_table = driver.findElement(By.className("main_table"));
//        WebElement PROTEIN_EXPRESSION = main_table.findElement(By.xpath("//table[4]"));
//        jsExecutor.executeScript("arguments[0].scrollIntoView(true);", PROTEIN_EXPRESSION);
//        saveImage(PROTEIN_EXPRESSION, key + File.separator + "PROTEIN_EXPRESSION");
//
//
//        //关闭浏览器
//        driver.quit();
//    }

    @Override
    public Reader buildReader(String key) {

        return new ProTeiNatLasReader(key);
    }


}
